<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>Peek - Chapter 4</title>
	<link rel='stylesheet' href='/strophe/public/css/jquery-ui-1.8.21.custom.css'>
	<link rel='stylesheet' href='/strophe/public/css/peek.css'>
	<script type="text/javascript" src="/strophe/public/js/jquery-1.7.2.min.js"></script>
	<script type="text/javascript" src="/strophe/public/js/jquery-ui-1.8.21.custom.min.js"></script>
	<script type="text/javascript" src="/strophe/public/js/strophe.js"></script>
	<script type="text/javascript" src="/strophe/public/js/flXHR.js"></script>
	<script type="text/javascript" src="/strophe/public/js/strophe.flxhr.js"></script>
	<script type="text/javascript">
		var Peek = {
			connection: null,
				
			showTraffic: function (body, type) {
				if (body.childNodes.length > 0) {
					var console = $('#console').get(0);
					var at_bottom = console.scrollTop >= console.scrollHeight - console.clientHeight;
					
					$.each(body.childNodes, function () {
						$('#console').append("<div class='" + type + "'>" 
								+ Peek.prettyXml(this) + "</div>");
					});
					
					if (at_bottom) {
						console.scrollTop = console.scrollHeight;
					}
				}
			},
			
			xml2html: function (s) {
				return s.replace(/&/g, "&amp;")
						.replace(/</g, "&lt;")
						.replace(/>/g, "&gt;");
			},
			
			prettyXml: function(xml, level) {
				var i, j;
				var result = [];
				if (!level) {
					level = 0;
				}
				
				result.push("<div class='xml_level" + level + "'>");
				result.push("<span class='xml_punc'>&lt;</span>");
				result.push("<span class='xml_tag'>");
				result.push(xml.tagName);
				result.push("</span>");
				
				// attributes
				var attrs = xml.attributes;
				var attr_lead = [];
				for (i = 0; i < xml.tagName.length + 1; i++) {
					attr_lead.push("&nbsp;");
				}
				attr_lead = attr_lead.join("");
				
				for (i = 0; i < attrs.length; i++) {
					result.push("&nbsp;<span class='xml_aname'>");
					result.push(attrs[i].nodeName);
					result.push("</span><span class='xml_punc'>='</span>");
					result.push("<span class='xml_avalue'>");
					result.push(attrs[i].nodeValue);
					result.push("</span><span class='xml_punc'>'</span>");
					
					if (i != attrs.length - 1) {
						result.push("</div><div class='xml_level" + level + "'>");
						result.push(attr_lead);
					}
				}
				
				if (xml.childNodes.length == 0) {
					result.push("<span class='xml_punc'>/&gt;</span></div>");
				}
				else {
					result.push("<span class='xml_punc'>&gt;</span></div>");
					
					// children
					$.each(xml.childNodes, function() {
						if (this.nodeType == 1) {
							result.push(Peek.prettyXml(this, level + 1));
						}
						else if (this.nodeType == 3) {
							result.push("<div class='xml_text xml_level" + (level + 1) + "'>");
							result.push(this.nodeValue);
							result.push("</div>");
						}
					});
					
					result.push("<div class='xml xml_level" + level + "'>");
					result.push("<span class='xml_punc'>&lt;/</span>");
					result.push("<span class='xml_tag'>");
					result.push(xml.tagName);
					result.push("</span>");
					result.push("<span class='xml_punc'>&gt;</span></div>");
				}
				
				return result.join("");
			},
			
			textToXml: function(text) {
				var doc = null;
				if (window['DOMParser']) {
					var parser = new DOMParser();
					doc = parser.parseFromString(text, 'text/xml');
				}
				else if (window['ActiveXObject']) {
					var doc = new ActiveXObject("MSXML2.DOMDocument");
					doc.async = false;
					doc.loadXML(text);
				}
				else {
					throw {
						type: 'PeekError',
						message: 'No DOMParser object found.'
					};
				}
				
				var elem = doc.documentElement;
				if ($(elem).filter('parseerror').length > 0) {
					return null;
				}
				return elem;
			}
		};
	
		$(document).ready(function () {
			$('#login_dialog').dialog({
				autoOpen: true,
				draggable: false,
				modal: true,
				title: 'Connect to XMPP',
				buttons: {
					"connect": function () {
						$(document).trigger('connect', {
							jid: $('#jid').val(),
							password: $('#password').val()
						});
						
						$('#password').val('');
						$(this).dialog('close');
					}
				}
			});
			
			$('#disconnect_button').click(function() {
				Peek.connection.disconnect();
			});
			
			$('#send_button').click(function() {
				var input = $('#input').val();
				var error = false;
				if (input.length > 0) {
					if (input[0] == '<') {
						var xml = Peek.textToXml($('#input').val());
						if (xml) {
							Peek.connection.send(xml);
							$('#input').val('');
						}
						else {
							error = true;
						}
					}
					else if (input[0] == '$') {
						try {
							var builder = eval(input);
							Peek.connection.send(builder);
						}
						catch(e) {
							console.log(e);
							error = true;
						}
					}
					else {
						error = true;
					}
				}
				
				if (error) {
					$('#input').animate({backgroundColor: "#faa"}, 200);	
				}				
			});
			
			$('#input').keypress(function() {
				$(this).css({backgroundColor: "#fff"});
			});
		});
		
		$(document).bind('connect', function (ev, data) {
			var conn = new Strophe.Connection('${config.boshUrl}');
			
			conn.xmlInput = function (body) {
				Peek.showTraffic(body, 'incoming');
			};
			
			conn.xmlOutput = function (body) {
				Peek.showTraffic(body, 'outgoing');
			};
			
			conn.connect(data.jid, data.password, function (status) {
				if (status == Strophe.Status.CONNECTED) {
					$(document).trigger('connected');
				}
				else if (status == Strophe.Status.DISCONNECTED) {
					$(document).trigger('disconnected');
				}
			});
			
			Peek.connection = conn;
		});
		
		$(document).bind('connected', function () {
			$('.button').removeAttr('disabled');
			$('#input').removeClass('disabled').removeAttr('disabled');
		});
		
		$(document).bind('disconnected', function () {
			$('.button').attr('disabled', 'disabled');
			$('#input').addClass('disabled').attr('disabled', 'disabled');
		});
	</script>
</head>
<body>
	<h1>Peek</h1>
	
	<div id="console"></div>
	<textarea id="input" class="disabled" disabled="disabled"></textarea>
	
	<div id="buttonbar">
		<input id="send_button" type="submit" value="Send Data" disabled="disabled" class="button">
		<input id="disconnect_button" type="submit" value="Disconnect" disabled="disabled" class="button">
	</div>
	
	<!-- login dialog -->
	<div id="login_dialog" class="hidden">
		<label>JID:</label><input type="text" id="jid" value="sejoonlim@${config.xmppDomain}">
		<label>Password:</label><input type="password" id="password" value="welcome1">
	</div>
</body>
</html>